/**
 * 
 */
package cn.dgfy.MyBatisStudy.plugin;

import java.util.Properties;

import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

/**
 * @author Tearfalls
 *
 */
/*
 * @Intercepts：完成插件签名
 */
@Intercepts({
	/*
	 *  @Signature：定义需要拦截的对象及方法
	 *  			拦截org.apache.ibatis.executor.statement.StatementHandler对象的parameterize(Statement statement)方法
	 */
	@Signature(
			type = org.apache.ibatis.executor.statement.StatementHandler.class, 
			method = "parameterize", 
			args = java.sql.Statement.class
	)
})
public class DisableQueryAdminPlugin implements Interceptor {
	
	/*
	 * 拦截目标对象的目标方法执行
	 */
	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		
		System.out.println("DisableQueryAdminPlugin : intercept(Invocation invocation) : invocation.getMethod() = " + invocation.getMethod());
		
		// 拿到当前拦截到的对象，即StatementHandler对象（org.apache.ibatis.executor.statement.RoutingStatementHandler类实例）
		Object target = invocation.getTarget();
		
		System.out.println("DisableQueryAdminPlugin : intercept(Invocation invocation) : target = " + target);
		
		// 通过MyBatis框架提供的SystemMetaObject类的forObject(target)静态方法拿到被拦截对象的元数据（MetaObject对象）
		MetaObject metaObject = SystemMetaObject.forObject(target);
		
		// 通过MetaObject对象的getValue(String name)方法获取到StatementHandler对象中的ParameterHandler对象的parameterObject
		// 字段值，在此例中即为查询参数id
		Object parameterValueObj = metaObject.getValue("parameterHandler.parameterObject");
		
		System.out.println("DisableQueryAdminPlugin : intercept(Invocation invocation) : parameterValueObj = " + parameterValueObj);
		
		// 对查询参数id的值进行判断
		if (parameterValueObj.equals(1)) {
			// 如果查询参数id的值为1
			System.out.println("DisableQueryAdminPlugin : intercept(Invocation invocation) : Change Value of parameterHandler.parameterObject to 2");
			
			// 通过MetaObject对象的setValue(String name, Object value)方法，将其值修改为2
			metaObject.setValue("parameterHandler.parameterObject", 2);
		}
		
		// invocation.proceed()方法就是执行目标对象的目标方法（即实际的parameterize(Statement statement)方法）并得到其返回值
		Object proceed = invocation.proceed();
		
		// 返回执行后的返回值
		return proceed;
	}
	
	/*
	 * 包装目标对象，即为目标对象创建一个代理对象
	 */
	@Override
	public Object plugin(Object target) {
		
		System.out.println("DisableQueryAdminPlugin : plugin(Object target) : target = " + target);
		
		// 借助MyBatis提供的Plugin类以指定的拦截器为目标对象创建一个动态代理
		// 也可以使用自定义的包装方法来为目标象创建动态代理
		Object wrap = Plugin.wrap(target, this);

		System.out.println("DisableQueryAdminPlugin : plugin(Object target) : wrap = " + wrap);
		
		return wrap;
	}
	
	/*
	 * 将插件注册时设置的property属性的值读入插件
	 */
	@Override
	public void setProperties(Properties properties) {
		System.out.println("DisableQueryAdminPlugin : setProperties(Properties properties) : properties = " + properties);
	}
	
}
